package zqwl_1dxrr16

import (
	"errors"
	"github.com/goburrow/serial"
	"github.com/zing-dev/go-bit-bytes/bit"
)

var ErrDateLength = errors.New("串口返回数据长度异常")

type Relay interface {
	OnAll() error

	On(byte) error

	OffAll() error

	Off(byte) error

	Status() ([]byte, error)

	Info() (*RelayInfo, error)

	Close()
}

type App interface {
	Run() error

	GetRelay() Relay
}

type Config struct {
	WebPort   uint // web 端口
	SlaveId   byte
	ResetTime uint // 重置时间,秒
	serial.Config
}

// RelayInfo 继电器信息
// 0x0000 ~ 0x000e
type RelayInfo struct {
	Address          uint16 `json:"address"` // 0x0000 取值范围：0X0000~0X00FF R/W
	originalBaudRate uint16 // 0x0001 实际波特率除以 100，比如 12 代表 1200，96 代表 9600,1152 代表 115200，10240 代表 102400
	BaudRate         uint32
	DataBits         byte   `json:"data_bits"` // 0x0002 仅支持 0X0007，0X0008，0X0009 三种 R/W
	originalParity   byte   // 0x0003 0X004E: 不校验；0X0045：偶校验；0X004F：奇校验
	Parity           byte   `json:"parity"` // 0x0003 0X004E: 不校验；0X0045：偶校验；0X004F：奇校验
	originalStopBits byte   // 0x0004 : 1bit 0X0002 : 1.5bit 0X0003 : 2bit R/W
	StopBits         byte   `json:"stop_bits"` // 0x0004 : 1bit 0X0002 : 1.5bit 0X0003 : 2bit R/W
	Version          string `json:"version"`   // 0x0005~0x000c 版本号 ASCII 表示，比如“IO-04-00”：IO 表示产品类型
	Restore          byte   `json:"restore"`   // 0x000d 恢复出厂 读无意义；当写 0x0001 时，控制板恢复出厂设置，写其他值无意义
	Reset            byte   `json:"reset"`     // 0x000e 复位 读无意义；当写 0x0001 时，控制板复位，写其他值无意义。
}

type relayInfo []byte

func parity(p byte) byte {
	switch p {
	case 0x004e:
		return 'N'
	case 0x0045:
		return 'E'
	case 0x004f:
		return 'O'
	default:
		return 'N'
	}
}

func stopBits(s byte) byte {
	switch s {
	case 1:
		return 1
	default:
		return 2
	}
}

func (r relayInfo) To() (R RelayInfo) {
	R.Address = bit.ToUint16(r[:2])
	R.originalBaudRate = bit.ToUint16(r[2:4])
	R.BaudRate = uint32(R.originalBaudRate) * 100
	R.DataBits = r[5]
	R.originalParity = r[7]
	R.Parity = parity(R.originalParity)
	R.StopBits = stopBits(r[9])
	R.Version = string([]byte{r[11], r[13], r[15], r[17], r[19], r[21], r[23], r[25]})
	return
}
